/*
    Geocache: some utilities for managing and visualizing geocache information
    Copyright (C) 2008  Gary Jackson

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.thegbomb.geocache;

import com.thegbomb.sphere.Point;
import com.thegbomb.sphere.Util;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;

public class GpxPointExtractor extends DefaultHandler2 {
    static private Logger logger = Logger.getLogger(GpxPointExtractor.class);
    
    private Set<Point> points = new HashSet<Point>();
    private String name = "";
    
    private boolean inWpt = false, getName = false;
    private int count = -1;
    
    private StringBuffer buf;
    
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        
        if (uri.equals("http://www.topografix.com/GPX/1/0")) {
            if (!inWpt && localName.equals("name")) {
                getName = true;
                buf = new StringBuffer();
            } else if (localName.equals("wpt")) {
                
                count++;
                inWpt = true;
                String lat = attributes.getValue("lat");
                String lon = attributes.getValue("lon");
                
                try {
                    double theta = Util.toRad(Double.parseDouble(lat));
                    double phi = Util.toRad(Double.parseDouble(lon));
                    
                    Point p = new Point(theta, phi);
                    points.add(p);
                } catch (NumberFormatException e) {
                    logger.error("waypoint " + count + " does not have parsable attribute format", e);
                    logger.info("error encountered at " + count + ", continuing");
                }
            }
            
        }
    }
    
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        
        if (uri.equals("http://www.topografix.com/GPX/1/0")) {
            if (!inWpt && localName.equals("name")) {
                name = buf.toString();
                getName = false;
            } else if (localName.equals("wpt"))
                inWpt = false;
        }
    }
    
    public void characters(char ch[], int start, int length) {
        if (getName) {
            buf.append(ch, start, length);
        }
    }
    
    public Set<Point> getPoints() {
        return Collections.unmodifiableSet(this.points);
    }
    
    public String getName() {
        return this.name;
    }
}
